#include <stdio.h>      // 标准输入输出库
#include <stdlib.h>     // 标准库，提供exit等函数
#include <sys/msg.h>    // 消息队列相关函数库

#define MSG_FILE "/tmp/passwd"  // 定义消息队列的标识文件

// 定义消息结构体
typedef struct msg_form{
    long mtype;    // 消息类型
    char mtext[256]; // 消息内容
} MSG;

int main()
{
    int msqid;     // 消息队列标识符
    key_t key;     // 消息队列的键值
    MSG msg; // 消息结构体实例

    // 生成消息队列的键值，使用/etc/passwd文件和字符'z'作为参数
    if ((key = ftok(MSG_FILE, 'z')) < 0)
    {
        perror("ftok error"); // 如果生成键值失败，输出错误信息
        exit(1); // 退出程序
    }

    // 创建消息队列，IPC_CREAT表示如果队列不存在则创建，0777是权限设置
    if ((msqid = msgget(key, IPC_CREAT | 0777)) == -1)
    {
        perror("msgget error"); // 如果创建消息队列失败，输出错误信息
        exit(1); // 退出程序
    }

    // 设置消息类型为888
    msg.mtype = 888;
    // 格式化消息内容，包含当前进程ID
    sprintf(msg.mtext, "hello, I'm client %d", getpid());
    // 发送消息到消息队列
    msgsnd(msqid, &msg, sizeof(msg.mtext), 0);

    // 从消息队列接收类型为999的消息
    msgrcv(msqid, &msg, 256, 999, 0);
    // 输出接收到的消息内容
    printf("Client: receive msg.mtext is: %s.\n", msg.mtext);
    // 输出接收到的消息类型
    printf("Client: receive msg.mtype is: %ld.\n", msg.mtype);

    return 0; // 程序正常结束
}